bytesareinthefiletosatisfytheread,anexceptionisthrowntoindicatean
error➋.Wealsodefineafunctionread_int()➌toreada4-byteintegerfrom
thefileinnetworkbyteorderwherethemostsignificantbyteoftheinteger
isfirstinthefile,aswellasdefineafunctiontoreadasinglebyte➍.Inthe
mainbodyofthescript,weopenafilepassedonthecommandlineandfirst
read a 4-byte value ➎, which we expect is the magic value BINX. Then the
codeentersaloop➏whilethere’sstilldatatoread,readingoutthelength,
thetwounknownvalues,andfinallythedataandthenprintingthevaluesto
theconsole.
WhenyourunthescriptinListing5-9andpassitthenameofabinary
filetoopen,alldatafromthefileshouldbeparsedandnoerrorsgeneratedif
ouranalysisthatthefirst4-byteblockwasthelengthofthedatasentonthe
networkiscorrect.Listing5-10 showsexample outputin Python3, which
doesabetterjobofdisplayingbinarystringsthanPython2.
$ python3 read_protocol.py bytes_outbound.bin
Magic: b'BINX'
Len: 15, Unk1: 1139, Unk2: 0, Data: b'\x03bob\x08user-box\x00'
Len: 18, Unk1: 1415, Unk2: 3, Data: b'\x03bob\x0cHow are you?'
Len: 28, Unk1: 2275, Unk2: 3, Data: b"\x03bob\x16This is nice isn't it?"
Len: 1, Unk1: 6, Unk2: 6, Data: b''
Len: 19, Unk1: 1145, Unk2: 5, Data: b'\x05alice\x00\x00\x00\x03\x03bob\x03Woo'
Len: 21, Unk1: 1677, Unk2: 2, Data: b"\x13I'm going away now!"
Listing5-10:ExampleoutputfromrunningListing5-9againstabinaryfile
HandlingInboundData
If you ran Listing 5-9 against an exported inbound data set, you would
immediatelygetanerrorbecausethere’snomagicstringBINXintheinbound
protocol,asshowninListing5-11.Ofcourse,thisiswhatwewouldexpectif
there were a mistake in our analysis and the length field wasn’t quite as
simpleaswethought.
$ python3 read_protocol.py bytes_inbound.bin
Magic: b'\x00\x00\x00\x02'
Length: 1, Unknown1: 16777216, Unknown2: 0, Data: b''
Traceback (most recent call last):
File "read_protocol.py", line 31, in <module>
data = read_bytes(f, length - 1)
File "read_protocol.py", line 9, in read_bytes
raise Exception("Not enough bytes in stream")
Exception: Not enough bytes in stream